4. java使用easyexcel导入excel

您所在的位置:网站首页 excel 导入工作表 表格名称带 4. java使用easyexcel导入excel

4. java使用easyexcel导入excel

2024-05-28 22:44| 来源: 网络整理| 查看: 265

文章目录 1.EXCEL模板数据格式、导入结果展示2.避坑防雷招待所[♥]2.1.与poi-Jar包文件版本冲突2.2.传入后台读取文件流报空指针 3.在线获取代码及模板3.1.Github获取3.2.CSDN下载 4.手把手操作慢放4.1.准备开发环境4.2.启动IDEA,新建项目[File->New->Project]4.3.点击Maven后,选择Project SDK[JDK版本],点击Next4.4.填写好项目名称-包名-版本信息后,点击Finish4.5.项目目录结构及文件介绍4.6.配置Maven依赖4.6.1.复制下面代码块中的依赖配置,粘贴到pom.xml中4.6.2.粘贴后,可对比参考下图中pom.xml配置依赖项 4.7.[src\main\java]目录下文件内容说明4.7.1.com\ts\demo\listener\FirstHeaderRowListener.java4.7.2.com\ts\demo\listener\SecondHeaderRowListener.java4.7.3.com\ts\demo\po\FirstHeaderPo.java4.7.4.com\ts\demo\po\SecondHeaderPo.java4.7.5.com\ts\demo\po\ImportDtataPo.java 4.8.[src\main\resources]目录下文件内容说明4.8.1.log4j.properties 4.9.[src\test\java\]目录下文件内容说明4.9.1.com\ts\demo\EasyexcelMultiHeaderTest.java 5.修改测试demo中模板的读取路径6.右键运行测试7.表演完毕,欢迎下次光临

1.EXCEL模板数据格式、导入结果展示

➸ 模板数据格式 在这里插入图片描述 ➸ 导入结果 在这里插入图片描述

2.避坑防雷招待所[♥] 2.1.与poi-Jar包文件版本冲突

报错信息:

com.alibaba.excel.exception.ExcelAnalysisException: java.lang.NoSuchMethodError: org.apache.poi.util.POILogger.log(ILjava/lang/Object;Ljava/lang/Throwable;)V

解决方案: 在pom.xml文件中找到 标签所引的依赖中,是否包含appach的poi-jar包,可通过通过按住鼠标,【Ctrl+左键】进入存在嫌疑的依赖文件中,查看是否有引入,如果有则使用标签,将重复的与easyexcel内冲突的或版本相同的过滤掉即可。如下:

xx.xx xx-xx-starter org.apache.poi poi-ooxml xx.xx.xx xx-xx 2.2.传入后台读取文件流报空指针

   当demo整合到web项目传入文件时,不能用变量接住文件流,不然后续读取的流对象始终是同一个,再次读取则是空指针。因为多个sheet页会循环读取,每读取一个sheet页,会自动将数据映射到实体类,我们需要再深克隆到实体对象中,再清空本次读取的数据,避免下次读取数据出现重复数据,然后再继续获取下一个sheet页的数据,就不会报空指针。

3.在线获取代码及模板 3.1.Github获取

  Sorry,网址爆炸,暂无法登录上传 ‘’-_-‘’

3.2.CSDN下载 文件名操作Easyexcel-批量导入模板-Sheet页内有多个标题行.xlsx下载Java使用Easyexcel批量导入多行表头的Demo.rar下载 4.手把手操作慢放 4.1.准备开发环境 开发工具IDEA_2020.3JDK版本1.8.0_60Maven版本apache-maven-3.6.0Maven仓库地址http://maven.aliyun.com/nexus/content/groups/public/ 4.2.启动IDEA,新建项目[File->New->Project]

在这里插入图片描述

4.3.点击Maven后,选择Project SDK[JDK版本],点击Next

在这里插入图片描述

4.4.填写好项目名称-包名-版本信息后,点击Finish

在这里插入图片描述

4.5.项目目录结构及文件介绍

在这里插入图片描述

4.6.配置Maven依赖 4.6.1.复制下面代码块中的依赖配置,粘贴到pom.xml中 8 8 1.7.25 com.alibaba easyexcel 2.2.0-beta2 org.slf4j slf4j-log4j12 ${slf4j.log4j.version} compile junit junit 4.12 test 4.6.2.粘贴后,可对比参考下图中pom.xml配置依赖项

在这里插入图片描述

4.7.[src\main\java]目录下文件内容说明 4.7.1.com\ts\demo\listener\FirstHeaderRowListener.java

  easyexcel的监听事件-读取sheet页第1个标题行内容。

package com.ts.demo.listener; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.exception.ExcelDataConvertException; import com.ts.demo.po.FirstHeaderPo; import org.apache.log4j.Logger; import java.util.ArrayList; import java.util.List; import java.util.Map; /** *

Title: 监听读取第1个标题行内容

* *

Description: 监听读取第1个标题行内容

* *

Copyright: Copyright bn(c) 2021

* *

Company: XX科技公司

* * @author tansir * @version 1.0 */ public class FirstHeaderRowListener extends AnalysisEventListener { /** * 日志 */ private Logger log = Logger.getLogger(FirstHeaderRowListener.class); /** * 行索引(多行表头) */ private static Integer rowIndex = 0; /** * 导入的障碍物数据 */ private static List list = new ArrayList(); /** * 每读一行内容都会调用invoke,在invoke中可以操作读取到的数据 * @param data 解析的数据 * @param context 解析的上下文对象 */ @Override public void invoke(FirstHeaderPo data, AnalysisContext context) { if(rowIndex // log.info(Arrays.toString(list.toArray())); } /** * 这里会一行行的返回头 * 监听器只需要重写这个方法就可以读取到头信息 * @param headMap * @param context */ @Override public void invokeHeadMap(Map headMap, AnalysisContext context) { // 读到下个sheet页的表头则重新计数,只读取障碍物的基础数据 rowIndex = 0; // log.info("解析到一条头数据:" + JSON.toJSONString(headMap)); } /** * 监听器实现这个方法就可以在读取数据的时候获取到异常信息 */ @Override public void onException(Exception exception, AnalysisContext context) { // 如果是某一个单元格的转换异常 能获取到具体行号 // 如果要获取头的信息 配合invokeHeadMap使用 if (exception instanceof ExcelDataConvertException) { ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException)exception; String errorMsgStr = "第{"+excelDataConvertException.getRowIndex()+"}行"; errorMsgStr += "第{"+ excelDataConvertException.getColumnIndex() +"}列解析异常。"; log.info(errorMsgStr); } } /** * 获取数据 */ public static List getDataList(){ return list; } /** * 清除数据 */ public static void clearDataList(){ list.clear(); } } 4.7.2.com\ts\demo\listener\SecondHeaderRowListener.java

  easyexcel的监听事件,读取sheet页第2个标题行内容。

package com.ts.demo.listener; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.ts.demo.po.SecondHeaderPo; import org.apache.log4j.Logger; import java.util.ArrayList; import java.util.List; /** *

Title: 监听读取第2个标题行内容

* *

Description: 监听读取第2个标题行内容

* *

Copyright: Copyright bn(c) 2021

* *

Company: XX科技公司

* * @author tansir */ public class SecondHeaderRowListener extends AnalysisEventListener { /** * 日志 */ private Logger log = Logger.getLogger(SecondHeaderRowListener.class); /** * 存储导入的经纬度数据 */ private static List list = new ArrayList(); /** * 每读一行内容都会调用invoke,在invoke中可以操作读取到的数据 * @param data 解析的数据 * @param context 解析的上下文对象 */ public void invoke(SecondHeaderPo data, AnalysisContext context) { list.add(data); } /** * 读取完整个文档后调用的方法 * @param analysisContext 上下文 */ public void doAfterAllAnalysed(AnalysisContext analysisContext) { // log.info(Arrays.toString(list.toArray())); } /** * 获取数据 */ public static List getDataList(){ return list; } /** * 清除数据 */ public static void clearDataList(){ list.clear(); } } 4.7.3.com\ts\demo\po\FirstHeaderPo.java

  模板文件Sheet页内第1个标题对应内容的实体类,不能理解,可结合4.5目录结构图理解。

package com.ts.demo.po; import com.alibaba.excel.annotation.ExcelProperty; import java.io.Serializable; /** *

Title: 第1个标题对应内容的实体类

* *

Description: 第1个标题对应内容的实体类

* *

Copyright: Copyright bn(c) 2021

* *

Company: XX科技公司

* * @author tansir * @version 1.0 */ public class FirstHeaderPo implements Serializable { /** * 版本 */ private static final long serialVersionUID = 10088L; @ExcelProperty("姓名*") private String name; @ExcelProperty("性别*") private String gender; @ExcelProperty("年龄*") private String age; @ExcelProperty("家庭地址") private String address; @ExcelProperty("感情状况") private String emotionState; @Override public String toString() { return "FirstHeaderPo{" + "name='" + name + '\'' + ", gender='" + gender + '\'' + ", age='" + age + '\'' + ", address='" + address + '\'' + ", emotionState='" + emotionState + '\'' + '}'; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getEmotionState() { return emotionState; } public void setEmotionState(String emotionState) { this.emotionState = emotionState; } } 4.7.4.com\ts\demo\po\SecondHeaderPo.java

  模板文件Sheet页内第2个标题对应内容的实体类,不能理解,可结合4.5目录结构图理解。

package com.ts.demo.po; import com.alibaba.excel.annotation.ExcelProperty; import java.io.Serializable; /** *

Title: 第2个标题对应内容的实体类

* *

Description: 第2个标题对应内容的实体类

* *

Copyright: Copyright bn(c) 2021

* *

Company: XX科技公司

* * @author tansir * @version 1.0 */ public class SecondHeaderPo implements Serializable { /** * 版本 */ private static final long serialVersionUID = 10089L; @ExcelProperty("开始时间*") private String startTime; @ExcelProperty("结束时间*") private String endTime; @ExcelProperty("食材名称*") private String foodName; @ExcelProperty("食材存量情况*") private String foodInventory; @Override public String toString() { return "SecondHeaderPo{" + "startTime='" + startTime + '\'' + ", endTime='" + endTime + '\'' + ", foodName='" + foodName + '\'' + ", foodInventory='" + foodInventory + '\'' + '}'; } public String getStartTime() { return startTime; } public void setStartTime(String startTime) { this.startTime = startTime; } public String getEndTime() { return endTime; } public void setEndTime(String endTime) { this.endTime = endTime; } public String getFoodName() { return foodName; } public void setFoodName(String foodName) { this.foodName = foodName; } public String getFoodInventory() { return foodInventory; } public void setFoodInventory(String foodInventory) { this.foodInventory = foodInventory; } } 4.7.5.com\ts\demo\po\ImportDtataPo.java

  导入的数据汇总的实体类。

package com.ts.demo.po; import java.util.List; /** *

Title: 导入的数据汇总实体类

* *

Description: 导入的数据汇总实体类

* *

Copyright: Copyright bn(c) 2021

* *

Company: XX科技公司

* * @author tansir * @version 1.0 */ public class ImportDtataPo { /** * sheet页编号 */ private Integer sheetNo; /** * sheet页名称 */ private String sheetName; /** * 第1个标题行对应数据 */ private FirstHeaderPo firstHeaderPo; /** * 第2个标题行对应数据 */ private List secondHeaderPoList; @Override public String toString() { return "ImportDtataPo{" + "sheetNo='" + sheetNo + '\'' + ", sheetName='" + sheetName + '\'' + ", firstHeaderPo=" + firstHeaderPo + ", secondHeaderPoList=" + secondHeaderPoList + '}'; } public Integer getSheetNo() { return sheetNo; } public void setSheetNo(Integer sheetNo) { this.sheetNo = sheetNo; } public String getSheetName() { return sheetName; } public void setSheetName(String sheetName) { this.sheetName = sheetName; } public FirstHeaderPo getFirstHeaderPo() { return firstHeaderPo; } public void setFirstHeaderPo(FirstHeaderPo firstHeaderPo) { this.firstHeaderPo = firstHeaderPo; } public List getSecondHeaderPoList() { return secondHeaderPoList; } public void setSecondHeaderPoList(List secondHeaderPoList) { this.secondHeaderPoList = secondHeaderPoList; } } 4.8.[src\main\resources]目录下文件内容说明 4.8.1.log4j.properties

  日志打印配置文件,不建立程序也会正常运行,只不过会出现警告,没有为log4j建立配置文件导致,会出现以下信息:

log4j:WARN Please initialize the log4j system properly. 4.9.[src\test\java]目录下文件内容说明 4.9.1.com\ts\demo\EasyexcelMultiHeaderTest.java

  easyexcel的demo测试类

package com.ts.demo; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.read.metadata.ReadSheet; import com.ts.demo.listener.FirstHeaderRowListener; import com.ts.demo.listener.SecondHeaderRowListener; import com.ts.demo.po.FirstHeaderPo; import com.ts.demo.po.ImportDtataPo; import com.ts.demo.po.SecondHeaderPo; import org.apache.log4j.Logger; import org.junit.Test; import java.io.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** *

Title: easyexcel-demo测试类

* *

Description: easyexcel-demo测试类

* *

Copyright: Copyright bn(c) 2021

* *

Company: XX科技公司

* * @author tansir * @version 1.0 */ public class EasyexcelDemoTest { /** * 日志 */ private Logger log = Logger.getLogger(EasyexcelDemoTest.class); /** * 导入文件所在路径 */ private static String FILE_PATH = "E:\\Desk\\测试多行表头多Sheet页导入模板.xlsx"; /** * 导入多个sheet页,且每个sheet页存在多个表头 */ @Test public void impMultipleHeaderAndSheet(){ // 导入结果 Map resultMap = new HashMap(); // 导入失败消息 StringBuffer bfrFailureMsg = new StringBuffer(); // 导入结果:0-失败,1-成功 int resultCode = 1; File file = new File(FILE_PATH); // 读取当前导入模块中有多少个sheet页 List readSheetList = EasyExcel.read(file).build().excelExecutor().sheetList(); // 记录当前到了那个sheet页 Integer sheetIndex = 0; // 导入的数据汇总实体类 List impDataPoList = new ArrayList(); for (ReadSheet readSheet : readSheetList) { ImportDtataPo importDtataPo = new ImportDtataPo(); Integer tempSheetNo = readSheet.getSheetNo(); String tempSheetName = readSheet.getSheetName(); try { EasyExcel.read(file, FirstHeaderPo.class, new FirstHeaderRowListener()) .sheet(tempSheetNo) .headRowNumber(2) .doRead(); EasyExcel.read(file, SecondHeaderPo.class, new SecondHeaderRowListener()) .sheet(tempSheetNo) .headRowNumber(4) .doRead(); importDtataPo.setSheetNo(tempSheetNo); importDtataPo.setSheetName(tempSheetName); // 反序列化对象[每读取一个sheet页,都需要清除上一次读取的数据,对象间有引用,避免汇总的数据被清除掉] ByteArrayOutputStream firstBos = new ByteArrayOutputStream(); ObjectOutputStream firstOos = new ObjectOutputStream(firstBos); // 序列化-first-header-row对象 firstOos.writeObject(FirstHeaderRowListener.getDataList().get(0)); ByteArrayInputStream firstBis = new ByteArrayInputStream(firstBos.toByteArray()); ObjectInputStream firstOis = new ObjectInputStream(firstBis); importDtataPo.setFirstHeaderPo((FirstHeaderPo) firstOis.readObject()); // 序列化-second-header-row对象 ByteArrayOutputStream secondBos = new ByteArrayOutputStream(); ObjectOutputStream secondOos = new ObjectOutputStream(secondBos); secondOos.writeObject(SecondHeaderRowListener.getDataList()); ByteArrayInputStream secondBis = new ByteArrayInputStream(secondBos.toByteArray()); ObjectInputStream secondOis = new ObjectInputStream(secondBis); importDtataPo.setSecondHeaderPoList((List) secondOis.readObject()); // 添加到汇总的实体类中 impDataPoList.add(importDtataPo); } catch (Exception e) { log.error(e); resultCode = 0; bfrFailureMsg.append("导入失败,请检查名称为《" + tempSheetName + "》的Sheet页是否符合模板、格式是否正确!").append(","); break; } finally { FirstHeaderRowListener.clearDataList(); SecondHeaderRowListener.clearDataList(); sheetIndex++; } } String finalBfrFailureMsg = bfrFailureMsg.toString(); if (!finalBfrFailureMsg.equals("")) { finalBfrFailureMsg = finalBfrFailureMsg.substring(0, finalBfrFailureMsg.lastIndexOf(",")); } resultMap.put("resultCode", resultCode); resultMap.put("bfrFailureMsg", finalBfrFailureMsg); System.out.println(); System.out.println((resultCode == 0) ? finalBfrFailureMsg : "======导入成功======"); impDataPoList.forEach(e->{ System.out.println(); System.out.println("第"+ (e.getSheetNo() + 1) +"个Sheet页,名称为:【" + e.getSheetName() +"】"); System.out.println("第1个标题对应内容的实体数据:"+ e.getFirstHeaderPo()); System.out.println("第2个标题对应内容的实数据:"+ e.getSecondHeaderPoList().size() +"条"); e.getSecondHeaderPoList().forEach(e2->{ System.out.println(e2); }); }); } } 5.修改测试demo中模板的读取路径

在这里插入图片描述

6.右键运行测试 7.表演完毕,欢迎下次光临

有问题欢迎留言反馈,再此记录,共同进步。 在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3